#ifndef TOP_MODEL_H_
#define TOP_MODEL_H_

#include "b_spline3.h"
#include "surface_utils.h"

class TopModel : public BSpline3{
	public:
		typedef std::vector<SurfaceUtils::Type> Types;
	private:
		float xref;
		float yref;
		float scale;
		bool closed;

		SurfaceUtils::Type current;
		Types types;
	public:
		TopModel(){
			this->closed=false;
			this->xref  = 0.5f;
			this->yref  = 0.5f;
			this->scale = 12.0f;
			this->current = SurfaceUtils::BASE;
		}

		TopModel(float xref,float yref,float scale){
			this->closed=false;
			this->xref = xref;
			this->yref = yref;
			this->scale = scale;
			this->current =SurfaceUtils::BASE;
		}

		~TopModel(){}

		float getXRef(){ return xref; }
		float getYRef(){ return yref; }
		float getScale(){ return scale; }

		SurfaceUtils::Type getSurfaceType(unsigned int segment){
			return this->types[segment];
		}

		const Types& getTypes(){
			return this->types;
		}

		void addSegmentType(unsigned int segment,SurfaceUtils::Type type){
			if(segment>this->types.size())
				this->types.push_back(type);
			else
				this->types[segment] = type;
		}

		void addSegmentType(unsigned int segment){
			addSegmentType(segment,this->current);
		}

		unsigned int segmentCount(){
			return this->types.size();
		}

		void setCurrent(SurfaceUtils::Type type){
			this->current = type;
		}

		SurfaceUtils::Type getCurrent(){
			return this->current;
		}

		void addPoint(Point point){
			BSpline3::addPoint(point);
			if(this->controlSize()>3){
				this->addSegmentType(this->controlSize()-3);
			}
		}

		void closeBSpline(){
			if(!closed){
				// Solo deben agregarse en el primer cierre
				closed=true;
				this->addSegmentType(this->types.size()+1);
				this->addSegmentType(this->types.size()+1);
				this->addSegmentType(this->types.size()+1);
				this->addSegmentType(this->types.size()+1);
			}

			BSpline3::closeBSpline();
		}

		void removePoint(Point point){
			unsigned int count=0,count2=0;
			bool found=false;
			for(std::vector<Point>::iterator it=this->control.begin();it!=control.end()&&!found;++it,count++){
				found=(*it==point);
			}
			BSpline3::removePoint(point);

			found=false;
			for(std::vector<SurfaceUtils::Type>::iterator it=this->types.begin();it!=this->types.end()&&!found;count2++){
				if(found=(count==count2))
					it = this->types.erase(it);
				else
					++it;
			}
		}
};

#endif /* TOP_MODEL_H_ */
